package fr.zombieGame;

/**
 * Polytech' Nice - Sophia Antipolis / SI3 / POO2
 * Annee 2011_2012
 * 
 * OMG Zombies !
 * 
 * Classe Zombie : modelisation d'un zombie
 *                 Zombie herite de Personnage
 * 
 * @author J. Harnetiaux et J. Lionne
 */


import java.util.Random;
import com.simulator.*;

import fr.comportement.*;

public class Zombie extends Personnage {

    private static final double TRANSFORMATION_ZOMBIE_FOU_PROBABILITE = 0.01;
    
    private boolean futurZombieFou;
    
    /**
     * Constructeur normal
     * Definit le comportement d'un zombie
     * @param nom
     * @param pointsDeVie
     */
    public Zombie(String nom, int pointsDeVie, final Field field, final Location location) {
        super(nom, pointsDeVie, field, location);
        force = 2;
        futurZombieFou = false;

        // Appliquer le comportement d'un zombie
        //
        this.deplacement = new Deplacement() {
            private static final int VITESSE = 1;

            public void bouger(Personnage perso) {
                Location newLocation = field.freeAvailableLocation(location, VITESSE);
                if (newLocation != null) setLocation(newLocation);
                else setMort();
            }

            public int getVitesse() {
                return VITESSE;
            }
        };
        this.espritCombatif = new CombatMainsNues();
        this.soutien = new PasDeSoutien();
    }

    /**
     * Accesseur
     * @return true si le zombie va se transformer, false sinon
     */
    public boolean isFuturZombieFou() {
        return futurZombieFou;
    }

    /**
     * Methode sans effet
     * Un zombie ne peut que ramper
     */
    @Override
    public void setDeplacement(Deplacement deplacement) {}

    /**
     * Change la strategie de combat du zombie
     * Un zombie ne peut que mordre ou combattre a mains nues
     */
    @Override
    public void setEspritCombatif(EspritCombatif espritCombatif) {
        // Ne rien faire si la strategie de combat proposee n'est pas valide pour un zombie
        //
        if(!(espritCombatif instanceof Morsure) && !(espritCombatif instanceof CombatMainsNues)) return;

        // Appliquer la strategie de combat
        //
        this.espritCombatif = espritCombatif;
    }

    /**
     * Methode sans effet
     * Un zombie est trop primitif pour soigner ses congenaires
     */
    @Override
    public void setSoutien(Soutien soutien) {}

    /**
     * Surcharge de la methode crier
     */
    @Override
    public void crier(String str) {
        System.out.println(nom + " dit : BRAIIIIIINS !");
    }
    
    /**
     * Transforme un zombie en zombie fou
     * @return le zombie fou associe au zombie
     */
    public ZombieFou transformerEnZombieFou() {
        futurZombieFou = false;
        ZombieFou zombieFou = new ZombieFou(nom, pointsDeVie, field, location);
        return zombieFou;
    }

    /**
     * Joue le comportement du zombie
     */
    public void jouer() {
        // Si le zombie est vivant :
        //    - Se deplacer (s'il ne peut pas bouger il mourra de surpopulation)
        //    - Verifier si un personnage se trouve a cote
        //
        if (estVivant) {
            // Se deplacer a une localisation ou se trouve un ennemi
            //
            Location localisation = trouverEnnemi(location);
            if (localisation == null) {
                // Pas d'ennemi aux alentours - se deplacer sur une localisation dispo
                //
                localisation = field.freeAvailableLocation(location, deplacement.getVitesse());
            }
            // Verifier s'il est possible de bouger
            //
            if (localisation != null) setLocation(localisation);
            else setMort();

            // Appliquer la fin de tour
            //
            this.appelerFinDeTour();
        }
    }

    /**
     * Methode declanchee a chaque fin de tour pour chaque personnage
     */
    @Override
    public void finDeTour() {
        randomTransformation();
    }
    
    /**
     * Change aleatoirement la strategie de combat du zombie
     */
    private void randomCombat() {
        Random rand = new Random();
        if(rand.nextBoolean())  {
            setEspritCombatif(new Morsure());
        }
        else setEspritCombatif(new CombatMainsNues());
    }
    
    /**
     * Change aleatoirement un zombie en zombie fou
     */
    private void randomTransformation() {
        if(this instanceof ZombieFou) return;
        
        Random rand = new Random();
        if(rand.nextDouble() <= TRANSFORMATION_ZOMBIE_FOU_PROBABILITE)  {
            futurZombieFou = true;
        }
    }
}
